<!doctype html>
<html style='font-size:14px !important'>
<head>
<meta charset='UTF-8'><meta name='viewport' content='width=device-width initial-scale=1'>
<title>main</title><link href='night/mermaid.dark.css' rel='stylesheet' type='text/css' />
<link href='night/codeblock.dark.css' rel='stylesheet' type='text/css' />
<link href='night/sourcemode.dark.css' rel='stylesheet' type='text/css' /><style type='text/css'>html {overflow-x: initial !important;}:root { --bg-color:#ffffff; --text-color:#333333; --select-text-bg-color:#B5D6FC; --select-text-font-color:auto; --monospace:"Lucida Console",Consolas,"Courier",monospace; }
html { font-size: 14px; background-color: var(--bg-color); color: var(--text-color); font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; }
body { margin: 0px; padding: 0px; height: auto; bottom: 0px; top: 0px; left: 0px; right: 0px; font-size: 1rem; line-height: 1.42857; overflow-x: hidden; background: inherit; }
iframe { margin: auto; }
a.url { word-break: break-all; }
a:active, a:hover { outline: 0px; }
.in-text-selection, ::selection { text-shadow: none; background: var(--select-text-bg-color); color: var(--select-text-font-color); }
#write { margin: 0px auto; height: auto; width: inherit; word-break: normal; word-wrap: break-word; position: relative; white-space: normal; overflow-x: visible; }
#write.first-line-indent p { text-indent: 2em; }
#write.first-line-indent li p, #write.first-line-indent p * { text-indent: 0px; }
#write.first-line-indent li { margin-left: 2em; }
.for-image #write { padding-left: 8px; padding-right: 8px; }
body.typora-export { padding-left: 30px; padding-right: 30px; }
.typora-export .footnote-line, .typora-export p { white-space: pre-wrap; }
@media screen and (max-width: 500px) {
  body.typora-export { padding-left: 0px; padding-right: 0px; }
  .CodeMirror-sizer { margin-left: 0px !important; }
  .CodeMirror-gutters { display: none !important; }
}
#write li > figure:first-child { margin-top: -20px; }
#write ol, #write ul { position: relative; }
img { max-width: 100%; vertical-align: middle; }
button, input, select, textarea { color: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; }
input[type="checkbox"], input[type="radio"] { line-height: normal; padding: 0px; }
*, ::after, ::before { box-sizing: border-box; }
#write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p, #write pre { width: inherit; }
#write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p { position: relative; }
h1, h2, h3, h4, h5, h6 { break-after: avoid-page; break-inside: avoid; orphans: 2; }
p { orphans: 4; }
h1 { font-size: 2rem; }
h2 { font-size: 1.8rem; }
h3 { font-size: 1.6rem; }
h4 { font-size: 1.4rem; }
h5 { font-size: 1.2rem; }
h6 { font-size: 1rem; }
.md-math-block, .md-rawblock, h1, h2, h3, h4, h5, h6, p { margin-top: 1rem; margin-bottom: 1rem; }
.hidden { display: none; }
.md-blockmeta { color: rgb(204, 204, 204); font-weight: 700; font-style: italic; }
a { cursor: pointer; }
sup.md-footnote { padding: 2px 4px; background-color: rgba(238, 238, 238, 0.7); color: rgb(85, 85, 85); border-radius: 4px; cursor: pointer; }
sup.md-footnote a, sup.md-footnote a:hover { color: inherit; text-transform: inherit; text-decoration: inherit; }
#write input[type="checkbox"] { cursor: pointer; width: inherit; height: inherit; }
figure { overflow-x: auto; margin: 1.2em 0px; max-width: calc(100% + 16px); padding: 0px; }
figure > table { margin: 0px !important; }
tr { break-inside: avoid; break-after: auto; }
thead { display: table-header-group; }
table { border-collapse: collapse; border-spacing: 0px; width: 100%; overflow: auto; break-inside: auto; text-align: left; }
table.md-table td { min-width: 80px; }
.CodeMirror-gutters { border-right: 0px; background-color: inherit; }
.CodeMirror { text-align: left; }
.CodeMirror-placeholder { opacity: 0.3; }
.CodeMirror pre { padding: 0px 4px; }
.CodeMirror-lines { padding: 0px; }
div.hr:focus { cursor: none; }
#write pre { white-space: pre-wrap; }
#write.fences-no-line-wrapping pre { white-space: pre; }
#write pre.ty-contain-cm { white-space: normal; }
.CodeMirror-gutters { margin-right: 4px; }
.md-fences { font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; overflow: visible; white-space: pre; background: inherit; position: relative !important; }
.md-diagram-panel { width: 100%; margin-top: 10px; text-align: center; padding-top: 0px; padding-bottom: 8px; overflow-x: auto; }
#write .md-fences.mock-cm { white-space: pre-wrap; }
.md-fences.md-fences-with-lineno { padding-left: 0px; }
#write.fences-no-line-wrapping .md-fences.mock-cm { white-space: pre; overflow-x: auto; }
.md-fences.mock-cm.md-fences-with-lineno { padding-left: 8px; }
.CodeMirror-line, twitterwidget { break-inside: avoid; }
.footnotes { opacity: 0.8; font-size: 0.9rem; margin-top: 1em; margin-bottom: 1em; }
.footnotes + .footnotes { margin-top: 0px; }
.md-reset { margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: top; background: 0px 0px; text-decoration: none; text-shadow: none; float: none; position: static; width: auto; height: auto; white-space: nowrap; cursor: inherit; -webkit-tap-highlight-color: transparent; line-height: normal; font-weight: 400; text-align: left; box-sizing: content-box; direction: ltr; }
li div { padding-top: 0px; }
blockquote { margin: 1rem 0px; }
li .mathjax-block, li p { margin: 0.5rem 0px; }
li { margin: 0px; position: relative; }
blockquote > :last-child { margin-bottom: 0px; }
blockquote > :first-child, li > :first-child { margin-top: 0px; }
.footnotes-area { color: rgb(136, 136, 136); margin-top: 0.714rem; padding-bottom: 0.143rem; white-space: normal; }
#write .footnote-line { white-space: pre-wrap; }
@media print {
  body, html { border: 1px solid transparent; height: 99%; break-after: avoid; break-before: avoid; }
  #write { margin-top: 0px; border-color: transparent !important; }
  .typora-export * { -webkit-print-color-adjust: exact; }
  html.blink-to-pdf { font-size: 13px; }
  .typora-export #write { padding-left: 1cm; padding-right: 1cm; padding-bottom: 0px; break-after: avoid; }
  .typora-export #write::after { height: 0px; }
  @page { margin: 20mm 0px; }
}
.footnote-line { margin-top: 0.714em; font-size: 0.7em; }
a img, img a { cursor: pointer; }
pre.md-meta-block { font-size: 0.8rem; min-height: 0.8rem; white-space: pre-wrap; background: rgb(204, 204, 204); display: block; overflow-x: hidden; }
p > img:only-child { display: block; margin: auto; }
p > .md-image:only-child { display: inline-block; width: 100%; text-align: center; }
#write .MathJax_Display { margin: 0.8em 0px 0px; }
.md-math-block { width: 100%; }
.md-math-block:not(:empty)::after { display: none; }
[contenteditable="true"]:active, [contenteditable="true"]:focus { outline: 0px; box-shadow: none; }
.md-task-list-item { position: relative; list-style-type: none; }
.task-list-item.md-task-list-item { padding-left: 0px; }
.md-task-list-item > input { position: absolute; top: 0px; left: 0px; margin-left: -1.2em; margin-top: calc(1em - 10px); }
.math { font-size: 1rem; }
.md-toc { min-height: 3.58rem; position: relative; font-size: 0.9rem; border-radius: 10px; }
.md-toc-content { position: relative; margin-left: 0px; }
.md-toc-content::after, .md-toc::after { display: none; }
.md-toc-item { display: block; color: rgb(65, 131, 196); }
.md-toc-item a { text-decoration: none; }
.md-toc-inner:hover { text-decoration: underline; }
.md-toc-inner { display: inline-block; cursor: pointer; }
.md-toc-h1 .md-toc-inner { margin-left: 0px; font-weight: 700; }
.md-toc-h2 .md-toc-inner { margin-left: 2em; }
.md-toc-h3 .md-toc-inner { margin-left: 4em; }
.md-toc-h4 .md-toc-inner { margin-left: 6em; }
.md-toc-h5 .md-toc-inner { margin-left: 8em; }
.md-toc-h6 .md-toc-inner { margin-left: 10em; }
@media screen and (max-width: 48em) {
  .md-toc-h3 .md-toc-inner { margin-left: 3.5em; }
  .md-toc-h4 .md-toc-inner { margin-left: 5em; }
  .md-toc-h5 .md-toc-inner { margin-left: 6.5em; }
  .md-toc-h6 .md-toc-inner { margin-left: 8em; }
}
a.md-toc-inner { font-size: inherit; font-style: inherit; font-weight: inherit; line-height: inherit; }
.footnote-line a:not(.reversefootnote) { color: inherit; }
.md-attr { display: none; }
.md-fn-count::after { content: "."; }
code, pre, samp, tt { font-family: var(--monospace); }
kbd { margin: 0px 0.1em; padding: 0.1em 0.6em; font-size: 0.8em; color: rgb(36, 39, 41); background: rgb(255, 255, 255); border: 1px solid rgb(173, 179, 185); border-radius: 3px; box-shadow: rgba(12, 13, 14, 0.2) 0px 1px 0px, rgb(255, 255, 255) 0px 0px 0px 2px inset; white-space: nowrap; vertical-align: middle; }
.md-comment { color: rgb(162, 127, 3); opacity: 0.8; font-family: var(--monospace); }
code { text-align: left; vertical-align: initial; }
a.md-print-anchor { white-space: pre !important; border-width: initial !important; border-style: none !important; border-color: initial !important; display: inline-block !important; position: absolute !important; width: 1px !important; right: 0px !important; outline: 0px !important; background: 0px 0px !important; text-decoration: initial !important; text-shadow: initial !important; }
.md-inline-math .MathJax_SVG .noError { display: none !important; }
.md-math-block .MathJax_SVG_Display { text-align: center; margin: 0px; position: relative; text-indent: 0px; max-width: none; max-height: none; min-height: 0px; min-width: 100%; width: auto; overflow-y: hidden; display: block !important; }
.MathJax_SVG_Display, .md-inline-math .MathJax_SVG_Display { width: auto; margin: inherit; display: inline-block !important; }
.MathJax_SVG .MJX-monospace { font-family: var(--monospace); }
.MathJax_SVG .MJX-sans-serif { font-family: sans-serif; }
.MathJax_SVG { display: inline; font-style: normal; font-weight: 400; line-height: normal; zoom: 90%; text-indent: 0px; text-align: left; text-transform: none; letter-spacing: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; padding: 0px; margin: 0px; }
.MathJax_SVG * { transition: none; }
.MathJax_SVG_Display svg { vertical-align: middle !important; margin-bottom: 0px !important; }
.os-windows.monocolor-emoji .md-emoji { font-family: "Segoe UI Symbol", sans-serif; }
.md-diagram-panel > svg { max-width: 100%; }
[lang="mermaid"] svg, [lang="flow"] svg { max-width: 100%; }
[lang="mermaid"] .node text { font-size: 1rem; }
table tr th { border-bottom: 0px; }
video { max-width: 100%; display: block; margin: 0px auto; }
iframe { max-width: 100%; width: 100%; border: none; }
.highlight td, .highlight tr { border: 0px; }


.CodeMirror { height: auto; }
.CodeMirror.cm-s-inner { background: inherit; }
.CodeMirror-scroll { overflow-y: hidden; overflow-x: auto; z-index: 3; }
.CodeMirror-gutter-filler, .CodeMirror-scrollbar-filler { background-color: rgb(255, 255, 255); }
.CodeMirror-gutters { border-right: 1px solid rgb(221, 221, 221); background: inherit; white-space: nowrap; }
.CodeMirror-linenumber { padding: 0px 3px 0px 5px; text-align: right; color: rgb(153, 153, 153); }
.cm-s-inner .cm-keyword { color: rgb(119, 0, 136); }
.cm-s-inner .cm-atom, .cm-s-inner.cm-atom { color: rgb(34, 17, 153); }
.cm-s-inner .cm-number { color: rgb(17, 102, 68); }
.cm-s-inner .cm-def { color: rgb(0, 0, 255); }
.cm-s-inner .cm-variable { color: rgb(0, 0, 0); }
.cm-s-inner .cm-variable-2 { color: rgb(0, 85, 170); }
.cm-s-inner .cm-variable-3 { color: rgb(0, 136, 85); }
.cm-s-inner .cm-string { color: rgb(170, 17, 17); }
.cm-s-inner .cm-property { color: rgb(0, 0, 0); }
.cm-s-inner .cm-operator { color: rgb(152, 26, 26); }
.cm-s-inner .cm-comment, .cm-s-inner.cm-comment { color: rgb(170, 85, 0); }
.cm-s-inner .cm-string-2 { color: rgb(255, 85, 0); }
.cm-s-inner .cm-meta { color: rgb(85, 85, 85); }
.cm-s-inner .cm-qualifier { color: rgb(85, 85, 85); }
.cm-s-inner .cm-builtin { color: rgb(51, 0, 170); }
.cm-s-inner .cm-bracket { color: rgb(153, 153, 119); }
.cm-s-inner .cm-tag { color: rgb(17, 119, 0); }
.cm-s-inner .cm-attribute { color: rgb(0, 0, 204); }
.cm-s-inner .cm-header, .cm-s-inner.cm-header { color: rgb(0, 0, 255); }
.cm-s-inner .cm-quote, .cm-s-inner.cm-quote { color: rgb(0, 153, 0); }
.cm-s-inner .cm-hr, .cm-s-inner.cm-hr { color: rgb(153, 153, 153); }
.cm-s-inner .cm-link, .cm-s-inner.cm-link { color: rgb(0, 0, 204); }
.cm-negative { color: rgb(221, 68, 68); }
.cm-positive { color: rgb(34, 153, 34); }
.cm-header, .cm-strong { font-weight: 700; }
.cm-del { text-decoration: line-through; }
.cm-em { font-style: italic; }
.cm-link { text-decoration: underline; }
.cm-error { color: red; }
.cm-invalidchar { color: red; }
.cm-constant { color: rgb(38, 139, 210); }
.cm-defined { color: rgb(181, 137, 0); }
div.CodeMirror span.CodeMirror-matchingbracket { color: rgb(0, 255, 0); }
div.CodeMirror span.CodeMirror-nonmatchingbracket { color: rgb(255, 34, 34); }
.cm-s-inner .CodeMirror-activeline-background { background: inherit; }
.CodeMirror { position: relative; overflow: hidden; }
.CodeMirror-scroll { height: 100%; outline: 0px; position: relative; box-sizing: content-box; background: inherit; }
.CodeMirror-sizer { position: relative; }
.CodeMirror-gutter-filler, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-vscrollbar { position: absolute; z-index: 6; display: none; }
.CodeMirror-vscrollbar { right: 0px; top: 0px; overflow: hidden; }
.CodeMirror-hscrollbar { bottom: 0px; left: 0px; overflow: hidden; }
.CodeMirror-scrollbar-filler { right: 0px; bottom: 0px; }
.CodeMirror-gutter-filler { left: 0px; bottom: 0px; }
.CodeMirror-gutters { position: absolute; left: 0px; top: 0px; padding-bottom: 30px; z-index: 3; }
.CodeMirror-gutter { white-space: normal; height: 100%; box-sizing: content-box; padding-bottom: 30px; margin-bottom: -32px; display: inline-block; }
.CodeMirror-gutter-wrapper { position: absolute; z-index: 4; background: 0px 0px !important; border: none !important; }
.CodeMirror-gutter-background { position: absolute; top: 0px; bottom: 0px; z-index: 4; }
.CodeMirror-gutter-elt { position: absolute; cursor: default; z-index: 4; }
.CodeMirror-lines { cursor: text; }
.CodeMirror pre { border-radius: 0px; border-width: 0px; background: 0px 0px; font-family: inherit; font-size: inherit; margin: 0px; white-space: pre; word-wrap: normal; color: inherit; z-index: 2; position: relative; overflow: visible; }
.CodeMirror-wrap pre { word-wrap: break-word; white-space: pre-wrap; word-break: normal; }
.CodeMirror-code pre { border-right: 30px solid transparent; width: fit-content; }
.CodeMirror-wrap .CodeMirror-code pre { border-right: none; width: auto; }
.CodeMirror-linebackground { position: absolute; left: 0px; right: 0px; top: 0px; bottom: 0px; z-index: 0; }
.CodeMirror-linewidget { position: relative; z-index: 2; overflow: auto; }
.CodeMirror-wrap .CodeMirror-scroll { overflow-x: hidden; }
.CodeMirror-measure { position: absolute; width: 100%; height: 0px; overflow: hidden; visibility: hidden; }
.CodeMirror-measure pre { position: static; }
.CodeMirror div.CodeMirror-cursor { position: absolute; visibility: hidden; border-right: none; width: 0px; }
.CodeMirror div.CodeMirror-cursor { visibility: hidden; }
.CodeMirror-focused div.CodeMirror-cursor { visibility: inherit; }
.cm-searching { background: rgba(255, 255, 0, 0.4); }
@media print {
  .CodeMirror div.CodeMirror-cursor { visibility: hidden; }
}


.cm-s-inner .cm-variable, .cm-s-inner .cm-operator, .cm-s-inner .cm-property { color: rgb(184, 191, 198); }
.cm-s-inner .cm-keyword { color: rgb(200, 143, 208); }
.cm-s-inner .cm-tag { color: rgb(125, 244, 106); }
.cm-s-inner .cm-attribute { color: rgb(117, 117, 228); }
.CodeMirror div.CodeMirror-cursor { border-left: 1px solid rgb(184, 191, 198); z-index: 3; }
.cm-s-inner .cm-string { color: rgb(210, 107, 107); }
.cm-s-inner .cm-comment, .cm-s-inner.cm-comment { color: rgb(218, 146, 74); }
.cm-s-inner .cm-header, .cm-s-inner .cm-def, .cm-s-inner.cm-header, .cm-s-inner.cm-def { color: rgb(141, 141, 240); }
.cm-s-inner .cm-quote, .cm-s-inner.cm-quote { color: rgb(87, 172, 87); }
.cm-s-inner .cm-hr { color: rgb(216, 213, 213); }
.cm-s-inner .cm-link { color: rgb(211, 211, 239); }
.cm-s-inner .cm-negative { color: rgb(217, 80, 80); }
.cm-s-inner .cm-positive { color: rgb(80, 230, 80); }
.cm-s-inner .cm-string-2 { color: rgb(255, 85, 0); }
.cm-s-inner .cm-meta, .cm-s-inner .cm-qualifier { color: rgb(183, 179, 179); }
.cm-s-inner .cm-builtin { color: rgb(243, 179, 248); }
.cm-s-inner .cm-bracket { color: rgb(153, 153, 119); }
.cm-s-inner .cm-atom, .cm-s-inner.cm-atom { color: rgb(132, 182, 203); }
.cm-s-inner .cm-number { color: rgb(100, 171, 143); }
.cm-s-inner .cm-variable { color: rgb(184, 191, 198); }
.cm-s-inner .cm-variable-2 { color: rgb(159, 186, 213); }
.cm-s-inner .cm-variable-3 { color: rgb(28, 198, 133); }
.CodeMirror-selectedtext, .CodeMirror-selected { background: rgb(74, 137, 220); text-shadow: none; color: rgb(255, 255, 255) !important; }
.CodeMirror-gutters { border-right: none; }


:root { --bg-color: #363B40; --side-bar-bg-color: #2E3033; --text-color: #b8bfc6; --select-text-bg-color:#4a89dc; --control-text-color: #b7b7b7; --control-text-hover-color: #eee; --window-border: 1px solid #555; --active-file-bg-color: rgb(34, 34, 34); --active-file-border-color: #8d8df0; --active-file-text-color: white; --item-hover-bg-color: #70717d; --item-hover-text-color: white; --primary-color: #6dc1e7; --rawblock-edit-panel-bd: #4B535A; }
html { font-size: 16px; }
html, body { text-size-adjust: 100%; background: var(--bg-color); fill: currentcolor; }
#write { max-width: 914px; padding-top: 20px; }
html, body, button, input, select, textarea, div.code-tooltip-content { color: rgb(184, 191, 198); }
div.code-tooltip, .md-hover-tip .md-arrow::after { background: rgb(75, 83, 90); }
.popover.bottom > .arrow::after { border-bottom-color: rgb(75, 83, 90); }
html, body, button, input, select, textarea { font-style: normal; line-height: 1.625rem; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; }
hr { height: 2px; border: 0px; margin: 24px 0px !important; }
h1, h2, h3, h4, h5, h6 { font-family: "Lucida Grande", Corbel, sans-serif; font-weight: normal; clear: both; word-wrap: break-word; margin: 0px; padding: 0px; color: rgb(222, 222, 222); }
h1 { font-size: 2.5rem; line-height: 2.75rem; margin-bottom: 1.5rem; letter-spacing: -1.5px; }
h2 { font-size: 1.63rem; line-height: 1.875rem; margin-bottom: 1.5rem; letter-spacing: -1px; font-weight: bold; }
h3 { font-size: 1.17rem; line-height: 1.5rem; margin-bottom: 1.5rem; letter-spacing: -1px; font-weight: bold; }
h4 { font-size: 1.12rem; line-height: 1.375rem; margin-bottom: 1.5rem; color: white; }
h5 { font-size: 0.97rem; line-height: 1.25rem; margin-bottom: 1.5rem; font-weight: bold; }
h6 { font-size: 0.93rem; line-height: 1rem; margin-bottom: 0.75rem; color: white; }
@media (min-width: 980px) {
  h3.md-focus::before, h4.md-focus::before, h5.md-focus::before, h6.md-focus::before { color: rgb(221, 221, 221); border: 1px solid rgb(221, 221, 221); border-radius: 3px; position: absolute; left: -1.64286rem; top: 0.357143rem; float: left; font-size: 9px; padding-left: 2px; padding-right: 2px; vertical-align: bottom; font-weight: normal; line-height: normal; }
  h3.md-focus::before { content: "h3"; }
  h4.md-focus::before { content: "h4"; }
  h5.md-focus::before { content: "h5"; top: 0px; }
  h6.md-focus::before { content: "h6"; top: 0px; }
}
a { text-decoration: none; outline: 0px; }
a:hover { outline: 0px; }
a:focus { outline: dotted thin; }
sup.md-footnote { background-color: rgb(85, 85, 85); color: rgb(221, 221, 221); }
p { word-wrap: break-word; }
p, ul, dd, ol, hr, address, pre, table, iframe, .wp-caption, .wp-audio-shortcode, .wp-video-shortcode { margin-top: 0px; margin-bottom: 1.5rem; }
li > blockquote { margin-bottom: 0px; }
audio:not([controls]) { display: none; }
[hidden] { display: none; }
.in-text-selection, ::selection { background: rgb(74, 137, 220); color: rgb(255, 255, 255); text-shadow: none; }
ul, ol { padding: 0px 0px 0px 1.875rem; }
ul { list-style: square; }
ol { list-style: decimal; }
ul ul, ol ol, ul ol, ol ul { margin: 0px; }
b, th, dt, strong { font-weight: bold; }
i, em, dfn, cite { font-style: italic; }
blockquote { margin: 35px 0px 1.875rem 1.875rem; border-left: 2px solid rgb(71, 77, 84); padding-left: 30px; }
pre, code, kbd, tt, var { background: rgba(0, 0, 0, 0.05); font-size: 0.875rem; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; }
kbd { padding: 2px 4px; font-size: 90%; color: rgb(255, 255, 255); background-color: rgb(51, 51, 51); border-radius: 3px; box-shadow: rgba(0, 0, 0, 0.25) 0px -1px 0px inset; }
pre.md-fences { padding: 10px 30px; margin-bottom: 20px; border: 1px solid; }
.md-fences .code-tooltip { bottom: -3.2em; }
.enable-diagrams pre.md-fences[lang="sequence"] .code-tooltip, .enable-diagrams pre.md-fences[lang="flow"] .code-tooltip, .enable-diagrams pre.md-fences[lang="mermaid"] .code-tooltip { bottom: -2.2em; right: 4px; }
code, kbd, tt, var { padding: 2px 5px; }
table { max-width: 100%; width: 100%; border-collapse: collapse; border-spacing: 0px; }
th, td { padding: 5px 10px; vertical-align: top; }
a { transition: all 0.2s ease-in-out; }
hr { background: rgb(71, 77, 84); }
h1 { margin-top: 2em; }
a { color: rgb(224, 224, 224); text-decoration: underline; }
a:hover { color: rgb(255, 255, 255); }
.md-inline-math script { color: rgb(129, 177, 219); }
b, th, dt, strong { color: rgb(222, 222, 222); }
mark { background: rgb(211, 212, 14); }
blockquote { color: rgb(157, 162, 166); }
table a { color: rgb(222, 222, 222); }
th, td { border: 1px solid rgb(71, 77, 84); }
.task-list { padding-left: 0px; }
.md-task-list-item { padding-left: 1.25rem; }
.md-task-list-item > input { top: auto; }
.md-task-list-item > input::before { content: ""; display: inline-block; width: 0.875rem; height: 0.875rem; vertical-align: middle; text-align: center; border: 1px solid rgb(184, 191, 198); background-color: rgb(54, 59, 64); margin-top: -0.4rem; }
.md-task-list-item > input:checked::before, .md-task-list-item > input[checked]::before { content: "√"; font-size: 0.625rem; line-height: 0.625rem; color: rgb(222, 222, 222); }
.CodeMirror-gutters { background: transparent; border-right: 1px solid transparent; }
.auto-suggest-container { border: 0px; background-color: rgb(82, 92, 101); }
#typora-quick-open { background-color: rgb(82, 92, 101); }
#typora-quick-open input { background-color: rgb(82, 92, 101); border-width: 0px 0px 1px; border-top-style: initial; border-right-style: initial; border-left-style: initial; border-top-color: initial; border-right-color: initial; border-left-color: initial; border-image: initial; border-bottom-style: solid; border-bottom-color: grey; }
.typora-quick-open-item { background-color: inherit; color: inherit; }
.typora-quick-open-item.active { background-color: rgb(77, 139, 219); color: white; }
.typora-search-spinner > div { background-color: rgb(255, 255, 255); }
#write pre.md-meta-block { border-bottom: 1px dashed rgb(204, 204, 204); background: transparent; padding-bottom: 0.6em; line-height: 1.6em; }
.btn, .btn .btn-default { background: transparent; color: rgb(184, 191, 198); }
.ty-table-edit { border-top: 1px solid gray; background-color: rgb(54, 59, 64); }
.popover-title { background: transparent; }
.md-image > .md-meta { color: rgb(187, 187, 187); background: transparent; }
.md-expand.md-image > .md-meta { color: rgb(221, 221, 221); }
#write > h3::before, #write > h4::before, #write > h5::before, #write > h6::before { border: none; border-radius: 0px; color: rgb(136, 136, 136); text-decoration: underline; left: -1.4rem; top: 0.2rem; }
#write > h3.md-focus::before { top: 2px; }
#write > h4.md-focus::before { top: 2px; }
.md-toc-item { color: rgb(168, 194, 220); }
#write div.md-toc-tooltip { background-color: rgb(54, 59, 64); }
.dropdown-menu .btn:hover, .dropdown-menu .btn:focus, .md-toc .btn:hover, .md-toc .btn:focus { color: white; background: black; }
#toc-dropmenu { background: rgba(50, 54, 59, 0.93); border: 1px solid rgba(253, 253, 253, 0.15); }
#toc-dropmenu .divider { background-color: rgb(155, 155, 155); }
.outline-expander::before { top: 2px; }
#typora-sidebar { box-shadow: none; border-right: none; }
.sidebar-tabs { border-bottom: 0px; }
#typora-sidebar:hover .outline-title-wrapper { border-left: 1px dashed; }
.outline-title-wrapper .btn { color: inherit; }
.outline-item:hover { border-color: rgb(54, 59, 64); background-color: rgb(54, 59, 64); color: white; }
h1.md-focus .md-attr, h2.md-focus .md-attr, h3.md-focus .md-attr, h4.md-focus .md-attr, h5.md-focus .md-attr, h6.md-focus .md-attr, .md-header-span .md-attr { color: rgb(140, 142, 146); display: inline; }
.md-comment { color: rgb(90, 149, 227); opacity: 1; }
.md-inline-math g, .md-inline-math svg { stroke: rgb(184, 191, 198) !important; fill: rgb(184, 191, 198) !important; }
[md-inline="inline_math"] { color: rgb(156, 178, 233); }
#math-inline-preview .md-arrow::after { background: black; }
.modal-content { background: var(--bg-color); border: 0px; }
.modal-title { font-size: 1.5em; }
.modal-content input { background-color: rgba(26, 21, 21, 0.51); color: white; }
.modal-content .input-group-addon { background-color: rgba(0, 0, 0, 0.17); color: white; }
.modal-backdrop { background-color: rgba(174, 174, 174, 0.7); }
.modal-content .btn-primary { border-color: var(--primary-color); }
.md-table-resize-popover { background-color: rgb(75, 83, 90); }
.form-inline .input-group .input-group-addon { color: white; }
#md-searchpanel { border-bottom: 1px dashed grey; }
.context-menu, #spell-check-panel, #footer-word-count-info { background-color: rgb(66, 70, 74); }
.context-menu.dropdown-menu .divider, .dropdown-menu .divider { background-color: rgb(119, 119, 119); }
footer { color: inherit; }
@media (max-width: 1000px) {
  footer { border-top: none; }
  footer:hover { color: inherit; }
}
#file-info-file-path .file-info-field-value:hover { background-color: rgb(85, 85, 85); color: rgb(222, 222, 222); }
.megamenu-content, .megamenu-opened header { background: var(--bg-color); }
.megamenu-menu-panel h2, .megamenu-menu-panel h1, .long-btn { color: inherit; }
.megamenu-menu-panel input[type="text"] { background: inherit; border-width: 0px 0px 1px; border-top-style: initial; border-right-style: initial; border-left-style: initial; border-color: initial; border-image: initial; border-bottom-style: solid; }
#recent-file-panel-action-btn { background: inherit; border: 1px solid grey; }
.megamenu-menu-panel .btn:hover, .megamenu-menu-panel .btn:focus, .megamenu-menu-panel .btn.focus { color: white; }
.megamenu-menu-panel .dropdown-menu > li > a { color: inherit; background-color: rgb(47, 53, 58); text-decoration: none; }
.megamenu-menu-panel table td:nth-child(1) { color: inherit; font-weight: bold; }
.megamenu-menu-panel tbody tr:hover td:nth-child(1) { color: white; }
.modal-footer .btn-default, .modal-footer .btn-primary, .modal-footer .btn-default:not(:hover) { border: 1px solid transparent; }
.btn-default:hover, .btn-default:focus, .btn-default.focus, .btn-default:active, .btn-default.active, .open > .dropdown-toggle.btn-default { color: white; border: 1px solid rgb(221, 221, 221); background-color: inherit; }
.modal-header { border-bottom: 0px; }
.modal-footer { border-top: 0px; }
#recent-file-panel tbody tr:nth-child(2n-1) { background-color: transparent !important; }
.megamenu-menu-panel tbody tr:hover td:nth-child(2) { color: inherit; }
.megamenu-menu-panel .btn { border: 1px solid rgb(238, 238, 238); background: transparent; }
.mouse-hover .toolbar-icon.btn:hover, #w-full.mouse-hover, #w-pin.mouse-hover { background-color: inherit; }
.typora-node::-webkit-scrollbar { width: 5px; }
.typora-node::-webkit-scrollbar-thumb:vertical { background: rgba(250, 250, 250, 0.3); }
.typora-node::-webkit-scrollbar-thumb:vertical:active { background: rgba(250, 250, 250, 0.5); }
#w-unpin { background-color: rgb(65, 130, 196); }
#top-titlebar, #top-titlebar * { color: var(--item-hover-text-color); }
.typora-sourceview-on #toggle-sourceview-btn, #footer-word-count:hover, .ty-show-word-count #footer-word-count { background: rgb(51, 51, 51); }
#toggle-sourceview-btn:hover { color: rgb(238, 238, 238); background: rgb(51, 51, 51); }
.on-focus-mode .md-end-block:not(.md-focus):not(.md-focus-container) * { color: rgb(104, 104, 104) !important; }
.on-focus-mode .md-end-block:not(.md-focus) img, .on-focus-mode .md-task-list-item:not(.md-focus-container) > input { }
.on-focus-mode li[cid]:not(.md-focus-container) { color: rgb(104, 104, 104); }
.on-focus-mode .md-fences.md-focus .CodeMirror-code > :not(.CodeMirror-activeline) *, .on-focus-mode .CodeMirror.cm-s-inner:not(.CodeMirror-focused) * { color: rgb(104, 104, 104) !important; }
.on-focus-mode .md-focus, .on-focus-mode .md-focus-container { color: rgb(255, 255, 255); }
.on-focus-mode #typora-source .CodeMirror-code > :not(.CodeMirror-activeline) * { color: rgb(104, 104, 104) !important; }
#write .md-focus .md-diagram-panel { border: 1px solid rgb(221, 221, 221); margin-left: -1px; width: calc(100% + 2px); }
#write .md-focus.md-fences-with-lineno .md-diagram-panel { margin-left: auto; }
.md-diagram-panel-error { color: rgb(241, 144, 142); }
.active-tab-files #info-panel-tab-file, .active-tab-files #info-panel-tab-file:hover, .active-tab-outline #info-panel-tab-outline, .active-tab-outline #info-panel-tab-outline:hover { color: rgb(238, 238, 238); }
.sidebar-footer-item:hover, .footer-item:hover { background: inherit; color: white; }
.ty-side-sort-btn.active, .ty-side-sort-btn:hover, .selected-folder-menu-item a::after { color: white; }
#sidebar-files-menu { border: 1px solid; box-shadow: rgba(0, 0, 0, 0.79) 4px 4px 20px; background-color: var(--bg-color); }
.file-list-item { border-bottom: none; }
.file-list-item-summary { opacity: 1; }
.file-list-item.active:first-child { border-top: none; }
.file-node-background { height: 32px; }
.file-library-node.active > .file-node-content, .file-list-item.active { color: var(--active-file-text-color); }
.file-library-node.active > .file-node-background { background-color: var(--active-file-bg-color); }
.file-list-item.active { background-color: var(--active-file-bg-color); }
#ty-tooltip { background-color: black; color: rgb(238, 238, 238); }
#write { cursor: -webkit-image-set(url("night/cursor.png") 1x, url("night/cursor@2x.png") 2x) 8 8, auto; }
.md-task-list-item > input { margin-left: -1.3em; margin-top: calc(1rem - 10px); -webkit-appearance: none; }
.md-mathjax-midline { background-color: rgb(87, 97, 107); border-bottom: none; }





 .typora-export p, .typora-export .footnote-line {white-space: normal;} 
</style>
</head>
<body class='typora-export os-windows' >
<div  id='write'  class = 'is-node'><h1><a name='header-n0' class='md-header-anchor '></a>Running application binary in SRAM with bootloader on LPC5500 MCU</h1><p>Andrew SU (<a href='mailto:yong.su@nxp.com' target='_blank' class='url'>yong.su@nxp.com</a>), 2020-03</p><div class='md-toc' mdtype='toc'><p class="md-toc-content"><span class="md-toc-item md-toc-h1" data-ref="n0"><a class="md-toc-inner" style="cursor: pointer;" href="#header-n0">Running application binary in SRAM with bootloader on LPC5500 MCU</a></span><span class="md-toc-item md-toc-h2" data-ref="n4"><a class="md-toc-inner" style="cursor: pointer;" href="#header-n4">Introduction</a></span><span class="md-toc-item md-toc-h2" data-ref="n7"><a class="md-toc-inner" style="cursor: pointer;" href="#header-n7">Principle</a></span><span class="md-toc-item md-toc-h2" data-ref="n55"><a class="md-toc-inner" style="cursor: pointer;" href="#header-n55">Workflow</a></span><span class="md-toc-item md-toc-h3" data-ref="n57"><a class="md-toc-inner" style="cursor: pointer;" href="#header-n57">Create the application project would be run in SRAM</a></span><span class="md-toc-item md-toc-h3" data-ref="n64"><a class="md-toc-inner" style="cursor: pointer;" href="#header-n64">Create the bootloader project to copy the application's binary</a></span><span class="md-toc-item md-toc-h3" data-ref="n100"><a class="md-toc-inner" style="cursor: pointer;" href="#header-n100">Download and debug the application binary</a></span><span class="md-toc-item md-toc-h2" data-ref="n114"><a class="md-toc-inner" style="cursor: pointer;" href="#header-n114">Benchmark</a></span></p></div><h2><a name='header-n4' class='md-header-anchor '></a>Introduction</h2><p>In traditional MCU usage, the application executable image is downloaded into FLASH inside the chip, and run the code in FLASH directly. Per the hardware limitation, the speed of accessing to FLASH is much slower than the CPU&#39;s clock. Even the CACHE technology can improve the performance in some case, but it would also involve additional problems, like data synchronous problem. Developers would like to move some code to SRAM for better running performance, since the speed of accessing to SRAM is close to the CPU&#39;s clock and much faster than FLASH. However, the code in SRAM would be lost when the power is off and reset again, while only the FLASH can keep the code even the power is off.</p><p>As there are already some way to debug the code in SRAM within the IDE, but these ways would can only control the MCU when the power is always on. Once the POR (Power-On-Reset) occurs, the application loaded by external debugger would be lost. The way described in this paper would make a little improvement and resolves the issue that the code in SRAM can not be kept after the POR. In this paper, it shows a way of using customized bootloader to move the application image from FLASH to SRAM in booting period, and run it in SRAM, so that it can keep the image in FLASH but run in SRAM per every POR.</p><h2><a name='header-n7' class='md-header-anchor '></a>Principle</h2><p>Actually, the idea of using the customized bootloader is from dual core usage on LPC5500 MCU. when running the dual core application, the image for CPU1 (the slave core) should be built firstly. then it would be involved into the CPU0 (the master core)&#39;s project during the compile. in CPU0&#39;s application, when it is like to activate the CPU1, it would move the original RAW image data for CPU1 from preserved FLASH area to SRAMX, feed the base address of the image into the &quot;CPU1 boot address register&quot;, and finally enable the clock and release the CPU1 to run.</p><p>Even in the single core usage, the CPU0 can also be switched to the new running routine by setting a new base address to PC register in its own ARM Cortex-M33 core. Also, the stack pointer registers (PSP and MSP) should be updated, and the vector table should be remapped as well if the new application would run in a pure clean environment.</p><p>In the demo for this paper, the whole project would be divided into two standalone parts:</p><ul><li>application project. this project is opened to application developer. the coding for application project is just as the previous work running on FLASH, it can be even built standalone and used to create an executable binary file. the only difference is to use a customized linker file, to relocate the whole image to SRAM address space since they would be there when running. the application code in this period is using the so-called &quot;run-time address&quot;.</li><li>bootloader project. this project is playing the most important role now. it would be the default application running after the chip is power on. then it would copy the RAW data of application project&#39;s binary image manually to the indicated SRAM area. finally, do the magical things (setup PC, PSP, MSP and VTOR registers in the ARM core) to activate the CPU0 with the new environment for application image. there is a trick about downloading the application image into chip. even it can be downloaded through various kinds of ways, in the demo, with the easiest way, I just use the flashloader integrated in IDE (IAR) for bootloader project, as the application image can be downloaded into the chip along within the bootloader project. whatever, the application image should be downloaded into the chip, the application code in this period is using the so-called &quot;download-time address&quot;.</li></ul><p>The boot process from MCU Reset to application code would be in two steps, as in Figure 1.</p><p><img src='./image/figure_mcu_boot_two_steps.png' alt='' referrerPolicy='no-referrer' /></p><p>Figure 1 Two steps from MCU reset to application code</p><p>Another important thing is to arrange the memory area for each parts. there would be three part should be considered:</p><ul><li>application image in run-time</li><li>application image in download-time</li><li>bootloader image</li></ul><p>The application image in download-time and the bootloader&#39;s code would be co-existing in the FLASH. the application image in run-time and the bootloader&#39;s RAM data would be co-existing in the SRAM. in the demo project, the memory areas are allocated as in the Table 1.</p><p>Table 1 Memory allocation for the demo project</p><figure><table><thead><tr><th>Address</th><th>Usage</th><th>Comment</th></tr></thead><tbody><tr><td>0x2000_0000 - 0x2002_FFFF, 192KB</td><td>application code in run-time</td><td>SRAM0/1/2</td></tr><tr><td>0x2003_0000 - 0x2003_FFFF, 64KB</td><td>application data in run-time</td><td>SRAM3</td></tr><tr><td>0x0000_0000 - 0x0000_FFFF, 64KB</td><td>bootloader code</td><td>FLASH</td></tr><tr><td>0x2003_0000 - 0x2003_FFFF, 64KB</td><td>bootloader data</td><td>SRAM3</td></tr><tr><td>0x0001_0000 - 0x0003_FFFF, 192KB</td><td>application binary in download-time</td><td>FLASH</td></tr></tbody></table></figure><p>In the Table 1, it can be seen that the size of reserved memory space for application binary in download-time is the same  as the application code in run-time, as the binary in download-time would be copied to SRAM for run-time. The data space for application in run-time shares the same SRAM with the bootloader, as no conflict. Once the application is running, the bootloader would no longer run.</p><h2><a name='header-n55' class='md-header-anchor '></a>Workflow</h2><p>This section would show the detail description about creating the whole demo project (including application project and the bootloader project) step by step. In the demo project, it  lights on and off the LED on LPCXpresso55s69 EVK board. When the project is normally working, the red LED on the board would be on and off.</p><h3><a name='header-n57' class='md-header-anchor '></a>Create the application project would be run in SRAM</h3><p>The application project can be any user project with no code change specially for usage of bootloader. In the demo for this paper, a project is created from MCUXpresso SDK with a few modification for simplification, controlling the on-board red LED on and off. The only one and the most critical change is to update the linker file according to the Table 1.</p><p>In the &quot;LPC55S69_cm33_application_ram.icf&quot; file for application project, there are following code:</p><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="javascript"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="javascript"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><span><span>​</span>x</span></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">define</span> <span class="cm-variable">symbol</span> <span class="cm-variable">m_interrupts_start</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-operator">=</span> <span class="cm-number">0x20000000</span>; <span class="cm-comment">/* start from sram0. */</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">define</span> <span class="cm-variable">symbol</span> <span class="cm-variable">m_interrupts_end</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-operator">=</span> <span class="cm-number">0x2000013F</span>;</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">define</span> <span class="cm-variable">symbol</span> <span class="cm-variable">m_text_start</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-operator">=</span> <span class="cm-number">0x2000013F</span>;</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">define</span> <span class="cm-variable">symbol</span> <span class="cm-variable">m_text_end</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-operator">=</span> <span class="cm-number">0x2002FFFF</span>; <span class="cm-comment">/* end within sram2. */</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">define</span> <span class="cm-variable">symbol</span> <span class="cm-variable">m_data_start</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-operator">=</span> <span class="cm-number">0x20030000</span>; <span class="cm-comment">/* start from sram3. */</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">define</span> <span class="cm-variable">symbol</span> <span class="cm-variable">m_data_end</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-operator">=</span> <span class="cm-number">0x2003FFFF</span>; <span class="cm-comment">/* end within sram3. */</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 179px;"></div><div class="CodeMirror-gutters" style="display: none; height: 179px;"></div></div></div></pre><p>Also, please make sure the executable &quot;.bin&quot; file would be created after the building, as it could be executed directly after the copy work in bootloader project without any extraction. The Figure 2 shows this setting in IAR IDE.</p><p><img src='./image/figure_create_bin_file_in_iar.png' alt='' referrerPolicy='no-referrer' /></p><p>Figure 2 Create binary file in application project</p><h3><a name='header-n64' class='md-header-anchor '></a>Create the bootloader project to copy the application&#39;s binary</h3><p>The bootloader project is specially created to copy the application&#39;s binary after the POR. It could just simply do the copy work, with no operation to the peripheral, even do not change the clock system, just using the default clock after the POR. However, it integrated the application project&#39;s binary so that it can be downloaded into the FLASH inside the MCU through the IDE&#39;s flashloader. Of course, the application project&#39;s binary can be downloaded through the other way, for example the ISP or blhost.exe (the NXP&#39;s  bootloader client running on PC to communicate with the on-chip ROM). But using the IDE&#39;s flashloader is still the most simplest way for developer, just as they download the project during the debugging period.</p><ol start='' ><li>Linker file</li></ol><p>First of all, update the linker file according to the Table 1 for the bootloader project. There are codes in the &quot;LPC55S69_cm33_bootloader_flash.icf&quot; file:</p><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="javascript" style="break-inside: unset;"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="javascript"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">define</span> <span class="cm-variable">symbol</span> <span class="cm-variable">m_interrupts_start</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-operator">=</span> <span class="cm-number">0x00000000</span>;</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">define</span> <span class="cm-variable">symbol</span> <span class="cm-variable">m_interrupts_end</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-operator">=</span> <span class="cm-number">0x0000013F</span>;</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">define</span> <span class="cm-variable">symbol</span> <span class="cm-variable">m_text_start</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-operator">=</span> <span class="cm-number">0x00000140</span>;</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">define</span> <span class="cm-variable">symbol</span> <span class="cm-variable">m_text_end</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-operator">=</span> <span class="cm-number">0x0000FFFF</span>; <span class="cm-comment">/* end with first 64KB. */</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">define</span> <span class="cm-variable">exported</span> <span class="cm-variable">symbol</span> <span class="cm-variable">application_image_start</span> <span class="cm-operator">=</span> <span class="cm-number">0x00010000</span>; <span class="cm-comment">/* for application image. 192KB. */</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">define</span> <span class="cm-variable">exported</span> <span class="cm-variable">symbol</span> <span class="cm-variable">application_image_end</span> &nbsp; <span class="cm-operator">=</span> <span class="cm-number">0x0003FFFF</span>;</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">define</span> <span class="cm-variable">symbol</span> <span class="cm-variable">m_data_start</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-operator">=</span> <span class="cm-number">0x20030000</span>;</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">define</span> <span class="cm-variable">symbol</span> <span class="cm-variable">m_data_end</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-operator">=</span> <span class="cm-number">0x2003FFFF</span>; <span class="cm-comment">/* sram3. */</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">/* for user application binary. */</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">define</span> <span class="cm-variable">region</span> <span class="cm-variable">APPLICATION_region</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-operator">=</span> <span class="cm-variable">mem</span>:[<span class="cm-variable">from</span> <span class="cm-variable">application_image_start</span> <span class="cm-variable">to</span> <span class="cm-variable">application_image_end</span>];</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">define</span> <span class="cm-variable">block</span> <span class="cm-variable">SEC_APPLICATION_IMAGE_BLOCK</span> &nbsp; &nbsp; &nbsp; &nbsp;  { <span class="cm-variable">section</span> &nbsp;<span class="cm-variable">__sec_application</span> };</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">place</span> &nbsp;<span class="cm-keyword">in</span> <span class="cm-variable">APPLICATION_region</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  { <span class="cm-variable">block</span> <span class="cm-variable">SEC_APPLICATION_IMAGE_BLOCK</span> };</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 381px;"></div><div class="CodeMirror-gutters" style="display: none; height: 381px;"></div></div></div></pre><p>The first part defines the memory areas for bootloader project, and the application project&#39;s binary in download-time. The last part defines a memory block for the binary in bootloader project, so that it can be included into the bootloader project&#39;s binary (all in one) during the building. The section name &quot;__sec_application&quot; quoted here would be defined in the project&#39;s option dialog.</p><p>Please keep in mind that  the application project&#39;s binary should still be visible to bootloader project, since the bootloader project need to recognize it and move it from FLASH to SRAM.</p><ol start='2' ><li>Project option</li></ol><p>The work of including the pre-build application&#39;s binary into the bootloader project should be done in the project options dialog, shown as in Figure 3.</p><p><img src='./image/figure_link_the_prebuild_binary_into_iar_project.png' alt='' referrerPolicy='no-referrer' /></p><p>Figure 3 Link the pre-build binary file into bootloader project</p><p>In the &quot;Raw binary image&quot; box:</p><ul><li>File: &quot;$PROJ_DIR$\application_debug\application.bin&quot;</li><li>Symbol: &quot;_lpc5500_cm33_application_image&quot;</li><li>Section: &quot;__sec_application&quot;</li><li>Alignment: &quot;4&quot;</li></ul><p>The &quot;Symbol&quot; would be used in the current project&#39;s source code, the &quot;Section&quot; is defined here and would be quoted in current project&#39;s linker file.</p><ol start='3' ><li>Source code</li></ol><p>In the SystemInit() function, which is called before the main() function in the boot routine, it enables all the RAM bank to make sure the SRAM0/1/2/3 would be available for later work.</p><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="c"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="c"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable-3">void</span> <span class="cm-def">SystemInit</span>(<span class="cm-variable-3">void</span>)</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">{</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-comment">/* enable RAM banks that may be off by default at reset */</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">SYSCON</span><span class="cm-operator">-&gt;</span><span class="cm-variable">AHBCLKCTRLSET</span>[<span class="cm-number">0</span>] <span class="cm-operator">=</span> <span class="cm-variable">SYSCON_AHBCLKCTRL0_SRAM_CTRL1_MASK</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-operator">|</span> <span class="cm-variable">SYSCON_AHBCLKCTRL0_SRAM_CTRL2_MASK</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-operator">|</span> <span class="cm-variable">SYSCON_AHBCLKCTRL0_SRAM_CTRL3_MASK</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="cm-operator">|</span> <span class="cm-variable">SYSCON_AHBCLKCTRL0_SRAM_CTRL4_MASK</span>;</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">}</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 179px;"></div><div class="CodeMirror-gutters" style="display: none; height: 179px;"></div></div></div></pre><p>Then in the main() function, which is the entry of user application in a project, it copies the binary from FLASH memory to SRAM memory and jump to run the new binary.</p><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="c" style="break-inside: unset;"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="c"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#define APPLICATION_BOOT_ADDRESS (void *)0x20000000</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">extern</span> <span class="cm-variable-3">uint8_t</span> <span class="cm-variable">application_image_start</span>[]; <span class="cm-comment">/* defined in linker file. */</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable-3">int</span> <span class="cm-def">main</span>(<span class="cm-variable-3">void</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">{</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-comment">/* copy application image to sram0/1/2. */</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#pragma section = "__sec_application" </span><span class="cm-comment">/* this section is defined in project option dialog. */</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable-3">uint32_t</span> <span class="cm-variable">application_image_size</span> <span class="cm-operator">=</span> (<span class="cm-variable-3">uint32_t</span>)<span class="cm-variable">__section_end</span>(<span class="cm-string">"__sec_application"</span>) <span class="cm-operator">-</span> (<span class="cm-variable-3">uint32_t</span>)<span class="cm-operator">&amp;</span><span class="cm-variable">application_image_start</span>;</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-comment">/* copy the code for application from FLASH to the target memory. */</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">memcpy</span>(<span class="cm-variable">APPLICATION_BOOT_ADDRESS</span>, (<span class="cm-variable-3">void</span> <span class="cm-variable-3">*</span>)<span class="cm-variable">application_image_start</span>, <span class="cm-variable">application_image_size</span>);</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-comment">/* jump to the application image. */</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">JumpToImage</span>(<span class="cm-variable">APPLICATION_BOOT_ADDRESS</span>);</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">}</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 358px;"></div><div class="CodeMirror-gutters" style="display: none; height: 358px;"></div></div></div></pre><p>Note here the &quot;APPLICATION_BOOT_ADDRESS&quot; is defined as &quot;0x2000_0000&quot; to align with the linker file&#39;s setting in application project.</p><p>The &quot;JumpToImage()&quot; function is acting the most magic role. It resets the running environment for application code (vector table, stacks and the PC pointer), once the PC pointer is changed, the CPU would run to the new routine.</p><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="c" style="break-inside: unset;"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="c"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">typedef</span> <span class="cm-variable-3">void</span>(<span class="cm-operator">*</span><span class="cm-variable">func_0_t</span>)(<span class="cm-variable-3">void</span>); <span class="cm-comment">/* define the type of function with no parameter. */</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable-3">void</span> <span class="cm-def">JumpToImage</span>(<span class="cm-variable-3">void</span> <span class="cm-variable-3">*</span> <span class="cm-variable">addr</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">{</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable-3">uint32_t</span> <span class="cm-variable-3">*</span> <span class="cm-variable">vectorTable</span> <span class="cm-operator">=</span> (<span class="cm-variable-3">uint32_t</span> <span class="cm-variable-3">*</span>)<span class="cm-variable">addr</span>;</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable-3">uint32_t</span> <span class="cm-variable">sp_base</span> <span class="cm-operator">=</span> <span class="cm-variable">vectorTable</span>[<span class="cm-number">0</span>]; <span class="cm-comment">/* initial stack pointer. */</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">func_0_t</span> <span class="cm-variable">pc_func</span> <span class="cm-operator">=</span> (<span class="cm-variable">func_0_t</span>)(<span class="cm-variable">vectorTable</span>[<span class="cm-number">1</span>]); <span class="cm-comment">/* reset handler. */</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-comment">/* set new msp and psp. */</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">__set_MSP</span>(<span class="cm-variable">sp_base</span>);</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">__set_PSP</span>(<span class="cm-variable">sp_base</span>);</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-comment">/* remap the vector table. */</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">SCB</span><span class="cm-operator">-&gt;</span><span class="cm-variable">VTOR</span> <span class="cm-operator">=</span> <span class="cm-variable">addr</span>;</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-comment">/* jump to application. */</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">pc_func</span>();</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-comment">/* the code should never reach here. */</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">while</span> (<span class="cm-number">1</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  {}</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">}</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 493px;"></div><div class="CodeMirror-gutters" style="display: none; height: 493px;"></div></div></div></pre><h3><a name='header-n100' class='md-header-anchor '></a>Download and debug the application binary</h3><p>To run the demo:</p><ul><li>Build the application project firstly, and generate the binary file &quot;application.bin&quot;.</li><li>Build the bootloader project, to involve the the pre-build &quot;application.bin&quot;, and generate the all-in-one binary file &quot;bootloader.bin&quot;. (actually the format of generated executable file is not cared, since it would be downloaded using the tools integrated in the IDE).</li><li>Download the final all-in-one binary file in the bootloader project, using the download tool in IDE.</li><li>Terminate the debug window, reset the board by pressing the on-board reset button, and run the demo.</li><li>The red LED light on and off under the control of the application project. This means the demo is just running as expected.</li></ul><p>For the first download, the above steps should be followed one by one, to make sure the bootloader and the application part are both available running on the chip. Once the bootloader part is already downloaded, then for later debug, developer can load the RAM binary directly in application project. Since the stack pointer registers (MSP, PSP) and the vector table register (VTOR) are already setup by the bootloader, when loading the run-time application binary directly in application project, the debugger would write the binary directly to SRAM memory and start the application in debug window. However, if the developer wants to make the final application project run after the POR with no IDE and debugger&#39;s help, just need to follow the above steps again, to keep the application binary is stored in the FLASH memory that would not lost when the power is off.</p><h2><a name='header-n114' class='md-header-anchor '></a>Benchmark</h2><p>The EEMBC coremark test is used to show the performance improvement of running code in SRAM. In the test project, the coremark thread is used as the application part, while the bootloader part is still the same as in the simple demo project. The LPC55S69 MCU is running with 150MHz core clock, with IAR compiler for ARM. The iterator times is set to 800, so that we would not wait for a long time (more than 10 seconds) for each test case.</p><figure><table><thead><tr><th><img src='./image/figure_coremark_flash_o3.png' alt='' referrerPolicy='no-referrer' /></th><th><img src='./image/figure_coremark_ram_o3.png' alt='' referrerPolicy='no-referrer' /></th></tr></thead><tbody><tr><td>FLASH code</td><td>RAM code</td></tr></tbody></table></figure><p>Figure 4 EEMBC coremark records for FLASH code and RAM code</p><p>Finally, all the records in different optimization levels are summarized into Table 2.</p><p>Table 2 Coremark records on various compiler optimizations</p><figure><table><thead><tr><th>Optimization</th><th>FLASH code</th><th>RAM code</th></tr></thead><tbody><tr><td>-o0 (none)</td><td>112.39</td><td>191.25</td></tr><tr><td>-o1 (low)</td><td>131.39</td><td>213.62</td></tr><tr><td>-o2 (medium)</td><td>182.23</td><td>280.11</td></tr><tr><td>-o3 (high speed)</td><td>265.16</td><td>405.06</td></tr></tbody></table></figure><p><img src='./image/figure_coremark_records.png' alt='' referrerPolicy='no-referrer' /></p><p>Figure 5 Coremark records on various compiler optimizations</p><p>From the benchmark test, it can be seen that the image the image running in SRAM is much faster then in the FLASH.</p><p>&nbsp;</p><ul><li>End</li></ul></div>
</body>
</html>